/**
 * Android音频的采集 方案有两种：AudioRecord + OpenSLES
 * AudioRecord:
 *
 * OpenSL ES:
 */

#include "AndroidAudioCapture.h"

#define LOG_TAG "AndroidAudioCapture"

extern "C"
JNIEXPORT void JNICALL
Java_com_fan_play_media_capture_AudioCapture_onAudioFrame(JNIEnv *env, jobject thiz,
                                                          jbyteArray audio_buf, jint raw_type,
                                                          jlong native_ref) {

}

AndroidAudioCapture::AndroidAudioCapture(AudioDevice *pCapDev) : ICapture(pCapDev) {
  auto pEnv = JNIHelper::Instance()->getEnv();
  jclass captureClass = pEnv->FindClass("com/fan/play/media/capture/AudioCapture");

  auto initID = pEnv->GetMethodID(captureClass, "<init>", "(IIIJ)V");
  jobject captureObj = pEnv->NewObject(captureClass, initID, pCapDev->sampleRate,
                                       pCapDev->channelNum, pCapDev->sampleBitPer,
                                       reinterpret_cast<jlong>(this));

  //创建全局对象
  _CaptureClass = static_cast<jclass>(pEnv->NewGlobalRef(captureClass));
  _CaptureObj = pEnv->NewGlobalRef(captureObj);

  pCapDev->devState = DeviceState_Init;
}

AndroidAudioCapture::~AndroidAudioCapture() noexcept {
  _pDevice->devState = DeviceState_None;
}

void AndroidAudioCapture::startCapture() {
  if (_pDevice->devState == DeviceState_None)
    return;

  _pDevice->devState = DeviceState_Start;

  auto *pEnv = JNIHelper::Instance()->attachThread();
  auto startID = pEnv->GetMethodID(_CaptureClass, "start", "()Z");
  if (startID && pEnv->CallBooleanMethod(_CaptureObj, startID)) {
    LOG_ERROR("启动失败")
  }
}

void AndroidAudioCapture::stopCapture() {
  if (_pDevice->devState == DeviceState_None)
    return;

  _pDevice->devState = DeviceState_Stop;

  auto *pEnv = JNIHelper::Instance()->attachThread();
  auto stopID = pEnv->GetMethodID(_CaptureClass, "stop", "()V");
  if (stopID) {
    pEnv->CallVoidMethod(_CaptureObj, stopID);
  }

  //删除通过JNIEnv创建的全局对象
  if (!pEnv->IsSameObject(_CaptureObj, nullptr)) {
    pEnv->DeleteGlobalRef(_CaptureObj);
  }

  if (!pEnv->IsSameObject(_CaptureClass, nullptr)) {
    pEnv->DeleteGlobalRef(_CaptureClass);
  }

  JNIHelper::Instance()->detachThread();
}

int32_t AndroidAudioCapture::capacity() {
  return MediaType_Audio;
}

const char *AndroidAudioCapture::getClassName() {
  return "AndroidAudioCapture";
}